package com.todo.biz.application.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.todo.biz.application.convert.BizBusinessConvert;
import com.todo.biz.application.entity.bo.FeedbackBO;
import com.todo.biz.application.entity.bo.FeedbackDetailBO;
import com.todo.biz.application.entity.bo.FeedbackReplyBO;
import com.todo.biz.application.entity.condition.FeedbackConditionBO;
import com.todo.biz.application.service.FeedbackService;
import com.todo.biz.common.enums.FeedbackStatusEnum;
import com.todo.biz.infrastructure.entity.condition.FeedbackCondition;
import com.todo.biz.infrastructure.entity.po.FeedbackPO;
import com.todo.biz.infrastructure.repository.FeedbackRepository;
import com.todo.common.common.entity.response.page.PageResult;
import com.todo.common.common.enums.BizErrorCodeEnum;
import com.todo.common.common.exception.BizException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

/**
 * (Feedback)表服务实现类
 *
 * @author zhangwenxiang
 * @since 2024-03-04 00:19:46
 */
@Slf4j
@Service("feedbackService")
public class FeedbackServiceImpl implements FeedbackService {

    public static final int MAX_POSTED_FEEDBACK_COUNT = 10;

    @Resource
    private FeedbackRepository feedbackRepository;

    @Override
    public Boolean insertFeedback(FeedbackBO feedbackBO) {
        if (feedbackBO == null) {
            throw new BizException(BizErrorCodeEnum.PARAM_ERROR);
        }
        if (!feedbackBO.baseCheck()) {
            log.error("FeedbackService#insertFeedback 新增反馈信息失败 核心字段缺失 feedbackBO：【{}】", JSONObject.toJSONString(feedbackBO));
            throw new BizException(BizErrorCodeEnum.PARAM_ERROR, "核心字段缺失");
        }
        List<FeedbackPO> feedbackPOS = feedbackRepository.queryFeedbackListByUserAndStatus(feedbackBO.getCreateUser(), FeedbackStatusEnum.POSTED.getType());
        if (feedbackPOS != null && feedbackPOS.size() > MAX_POSTED_FEEDBACK_COUNT) {
            log.error("FeedbackService#insertFeedback 新增反馈信息失败 较多未处理的反馈,暂时无法再次提交 feedbackBO：【{}】", JSONObject.toJSONString(feedbackBO));
            throw new BizException(BizErrorCodeEnum.PARAM_ERROR, "您有较多未处理的反馈，请待平台处理后后再提交");
        }
        //新增默认状态为【已提交】
        feedbackBO.setStatus(FeedbackStatusEnum.POSTED);
        FeedbackPO feedbackPO = BizBusinessConvert.converToFeedbackPO(feedbackBO);
        Boolean insertResult = feedbackRepository.insertFeedbackPO(feedbackPO);
        return insertResult;
    }

    @Override
    public Boolean updateFeedback(FeedbackBO feedbackBO) {
        if (feedbackBO == null || feedbackBO.getId() == null) {
            throw new BizException(BizErrorCodeEnum.PARAM_ERROR);
        }
        FeedbackDetailBO alreadyFeedbackDetailBO = queryFeedbackById(feedbackBO.getId());
        if (alreadyFeedbackDetailBO == null) {
            log.error("FeedbackService#updateFeedback 更新反馈信息失败，数据为空 默认无法处理 feedbackBO：【{}】", JSONObject.toJSONString(feedbackBO));
            throw new BizException(BizErrorCodeEnum.DATA_NOT_EXIST);
        }
        if (!alreadyFeedbackDetailBO.getStatus().equals(FeedbackStatusEnum.POSTED)) {
            log.error("FeedbackService#updateFeedback 更新反馈信息失败，状态不允许更新 feedbackBO：【{}】", JSONObject.toJSONString(feedbackBO));
            throw new BizException(BizErrorCodeEnum.OPERATION_FAILED, "当前状态内容无法修改");
        }
        FeedbackPO feedbackPO = BizBusinessConvert.converToFeedbackPO(feedbackBO);
        Boolean updateResult = feedbackRepository.updateFeedbackPOById(feedbackPO);
        return updateResult;
    }

    @Override
    public Boolean replyFeedback(FeedbackReplyBO feedbackReplyBO) {
        if (feedbackReplyBO == null || feedbackReplyBO.getId() == null) {
            throw new BizException(BizErrorCodeEnum.PARAM_ERROR);
        }
        FeedbackDetailBO alreadyFeedbackDetailBO = queryFeedbackById(feedbackReplyBO.getId());
        if (alreadyFeedbackDetailBO == null) {
            log.error("FeedbackService#replyFeedback 回复反馈信息失败，数据为空 默认无法处理 feedbackReplyBO：【{}】", JSONObject.toJSONString(feedbackReplyBO));
            throw new BizException(BizErrorCodeEnum.DATA_NOT_EXIST);
        }
        //新增默认状态为【已回复】
        FeedbackPO feedbackPO = BizBusinessConvert.replyconverToFeedbackPO(feedbackReplyBO);
        feedbackPO.setStatus(FeedbackStatusEnum.REPLIED.getType());
        Boolean updateResult = feedbackRepository.updateFeedbackPOById(feedbackPO);
        return updateResult;
    }

    @Override
    public Boolean removeFeedbackById(Long id) {
        if (id == null || id < 0) {
            throw new BizException(BizErrorCodeEnum.PARAM_ERROR);
        }
        FeedbackDetailBO feedbackDetailBO = queryFeedbackById(id);
        if (feedbackDetailBO == null) {
            return true;
        }
        return feedbackRepository.removeFeedbackPOById(id);
    }

    @Override
    public Boolean updateStatusById(Long id, FeedbackStatusEnum oldStatus, FeedbackStatusEnum newStatus) {
        if (id == null || id < 0 || oldStatus == null || newStatus == null) {
            throw new BizException(BizErrorCodeEnum.PARAM_ERROR);
        }
        //状态流转初期不做校验
        FeedbackDetailBO feedbackDetailBO = queryFeedbackById(id);
        if (feedbackDetailBO == null) {
            log.error("FeedbackService#updateStatusById 更新反馈状态失败 数据为空 ID：【{}】", id);
            throw new BizException(BizErrorCodeEnum.DATA_NOT_EXIST);
        }
        //状态一致不在处理
        if (feedbackDetailBO.getStatus().equals(newStatus)) {
            return true;
        }
        Boolean updateResult = feedbackRepository.updateStatusById(id, oldStatus.getType(), newStatus.getType());
        return updateResult;
    }

    @Override
    public FeedbackDetailBO queryFeedbackById(Long id) {
        if (id == null || id < 0) {
            return null;
        }
        FeedbackPO feedbackPO = feedbackRepository.queryFeedbackPOById(id);
        return BizBusinessConvert.convertToFeedbackDetailBO(feedbackPO);
    }

    @Override
    public PageResult<FeedbackBO> queryFeedbackByCondition(FeedbackConditionBO feedbackConditionBO) {
        if (feedbackConditionBO == null) {
            return new PageResult<>();
        }
        FeedbackCondition condition = BizBusinessConvert.convertToFeedbackCondition(feedbackConditionBO);
        PageResult<FeedbackPO> pageResult = feedbackRepository.queryFeedbackByCondition(condition);
        if (pageResult == null) {
            return new PageResult<>();
        }
        PageResult<FeedbackBO> result = new PageResult<>();
        result.setResults(pageResult.getResults() == null ? null : pageResult.getResults().stream().map(BizBusinessConvert::convertToFeedbackBO).collect(Collectors.toList()));
        result.setPageCount(pageResult.getPageCount());
        result.setCurrentIndex(pageResult.getCurrentIndex());
        result.setTotal(pageResult.getTotal());
        result.setPageNum(pageResult.getPageNum());
        result.setHasNext(pageResult.isHasNext());
        result.setPageSize(pageResult.getPageSize());
        return result;
    }

    @Override
    public Boolean removeFeedbackByIdList(List<Long> idList) {
        if (CollectionUtils.isEmpty(idList)) {
            return true;
        }
        Boolean removeResult = feedbackRepository.removeFeedbackPOByIdList(idList);
        return removeResult;
    }
}
